package org.linphone.sub.audio;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.util.Log;

/**
 * Created by Xiang on 2018/4/4.
 */

public class AudioPlay {
	//log日志打印索引
	private static final String TAG = "AudioPlayer";
	//开启一个音频播放器的音频类型
	private static final int DEFAULT_STREAM_TYPE = AudioManager.STREAM_MUSIC;
	//音频采样率
	private static final int DEFAULT_SAMPLE_RATE = 48000;
	//音频声道类型，此处设置为双声道
	private static final int DEFAULT_CHANNEL_CONFIG = AudioFormat.CHANNEL_OUT_STEREO;
	//音频数据格式有8位和16位，此处设置为16位
	private static final int DEFAULT_AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
	//音频流类型
	private static final int DEFAULT_PLAY_MODE = AudioTrack.MODE_STREAM;

	//判断音频流是否开启，控制线程的启停
	private volatile boolean mIsPlayStarted = false;
	//音频流原生类
	private AudioTrack mAudioTrack;

	//volatile保证内存中数据实时更新
	private volatile boolean mIsLoopExit = false;

	//播放线程
	private Thread mPlayThread;

	//开启一个音频播放流线程
	public boolean startPlayer() {
		return startPlayer(DEFAULT_STREAM_TYPE, DEFAULT_SAMPLE_RATE, DEFAULT_CHANNEL_CONFIG, DEFAULT_AUDIO_FORMAT);
	}

	//开启一个音频播放流线程
	public boolean startPlayer(int streamType, int sampleRateInHz, int channelConfig, int audioFormat) {
		//检查判断音频是否已开启
		if (mIsPlayStarted) {
			Log.e(TAG, "播放器已开启 !");
			return false;
		}
		//获取音频播放最小字节数并判断传入参数的正确性
		int bufferSizeInBytes = AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
		if (bufferSizeInBytes == AudioTrack.ERROR_BAD_VALUE) {
			Log.e(TAG, "传入的参数错误 !");
			return false;
		}
		Log.i(TAG, "getMinBufferSize = " + bufferSizeInBytes + " bytes !");
		//获取一个音频播放线程并初始化数据
		mAudioTrack = new AudioTrack(streamType, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes*4, DEFAULT_PLAY_MODE);
		if (mAudioTrack.getState() == AudioTrack.STATE_UNINITIALIZED) {
			Log.e(TAG, "播放器初始化失败 !");
			return false;
		}
		mIsLoopExit = false;
		//开启播放线程并初始化
		mPlayThread = new Thread(new AudioPlayRunnable());
		mPlayThread.start();
		mIsPlayStarted = true;
		Log.i(TAG, "成功开启播放器 !");
		return true;
	}

	//停止播放流
	public void stopPlayer() {
		if (!mIsPlayStarted) {
			return;
		}
		mIsLoopExit = true;
		try {
			mPlayThread.interrupt();
			mPlayThread.join(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		if (mAudioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
			mAudioTrack.stop();
		}

		mAudioTrack.release();
		mIsPlayStarted = false;

		Log.i(TAG, "停止播放器 !");
	}

	//开始播放音频数据
	public boolean play(byte[] audioData, int offsetInBytes, int sizeInBytes) {
		if (!mIsPlayStarted) {
			Log.e(TAG, "播放器未开启 !");
			return false;
		}

		if (mAudioTrack.write(audioData, offsetInBytes, sizeInBytes) != sizeInBytes) {
			Log.e(TAG, "不能播放所有的音频数据 !");
		}

		Log.d(TAG, "播放了 " + sizeInBytes + " 字节 !");

		return true;
	}


	//录音线程核心
	private class AudioPlayRunnable implements Runnable {
		@Override
		public void run() {
			while (!mIsLoopExit) {
				mAudioTrack.play();
				//mAudioTrack.release();
			}
		}
	}

}
